#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
#include <limits>

int main() {
    // 读取图片
    cv::Mat image = cv::imread("../boxs.png"); // 替换为实际的图片路径
    if (image.empty()) {
        std::cerr << "无法加载图片！" << std::endl;
        return -1;
    }

    // 将图像从BGR颜色空间转换到HSV颜色空间
    cv::Mat hsv;
    cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);

    // 定义蓝色在HSV颜色空间中的阈值范围
    cv::Scalar lower_blue(105, 190, 180);
    cv::Scalar upper_blue(115, 255, 255);

    // 根据阈值创建掩膜，分离出蓝色区域
    cv::Mat mask;
    cv::inRange(hsv, lower_blue, upper_blue, mask);

    // 对掩膜进行形态学操作（开运算，去除噪声并平滑区域边界）
    cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
    cv::Mat opened_mask;
    cv::morphologyEx(mask, opened_mask, cv::MORPH_OPEN, kernel);

    // 查找蓝色区域中的轮廓
    std::vector<std::vector<cv::Point>> contours;
    cv::findContours(opened_mask, contours, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);

    std::cout << "检测到的轮廓数量: " << contours.size() << std::endl;

    // 定义参考矩形的参数
    const double REF_AREA = 200.0 * 280.0;
    const double REF_RATIO = 200.0 / 280.0;
    const double AREA_THRESHOLD = 0.5;  // 面积误差阈值（50%）
    const double RATIO_THRESHOLD = 0.2; // 长宽比误差阈值（20%）

    // 遍历轮廓
    for (size_t i = 0; i < contours.size(); ++i) {
        // 计算凸包
        std::vector<cv::Point> hull;
        cv::convexHull(contours[i], hull);

        // 获取最小外接旋转矩形
        cv::RotatedRect minRect = cv::minAreaRect(hull);
        cv::Point2f rectPoints[4];
        minRect.points(rectPoints);

        // 面积筛选
        double area = minRect.size.width * minRect.size.height;
        double area_diff = std::abs(area - REF_AREA) / REF_AREA;
        if (area_diff > AREA_THRESHOLD) {
            std::cout << "矩形 " << i + 1 << " 的面积差距过大，跳过。" << std::endl;
            continue;
        }

        // 绘制轮廓 黄色
        cv::drawContours(image, contours, static_cast<int>(i), cv::Scalar(0, 255, 255), 2);
        // 绘制凸包 绿色
        cv::drawContours(image, std::vector<std::vector<cv::Point>>{hull}, -1, cv::Scalar(0, 255, 0), 2);
        // 绘制最小外接旋转矩形 红色
        for (int j = 0; j < 4; ++j) {
            cv::line(image, rectPoints[j], rectPoints[(j + 1) % 4], cv::Scalar(0, 0, 255), 2);
        }

        // 提取旋转矩形区域并保存
        cv::Mat rotationMatrix = cv::getRotationMatrix2D(minRect.center, minRect.angle, 1.0);
        cv::Mat rotatedImage;
        cv::warpAffine(image, rotatedImage, rotationMatrix, image.size(), cv::INTER_CUBIC);

        cv::Size rectSize = minRect.size;
        if (minRect.angle < -45.0) {
            std::swap(rectSize.width, rectSize.height);
        }
        cv::Mat cropped;
        cv::getRectSubPix(rotatedImage, rectSize, minRect.center, cropped);

        // cv::Mat resized_cropped;
        // cv::resize(cropped, resized_cropped, cv::Size(200, 280));

        // 保存裁剪后的图像
        std::string cropped_filename = "rotated_rectangle_" + std::to_string(i + 1) + ".png";
        cv::imwrite(cropped_filename, cropped);
        std::cout << "矩形 " << i + 1 << " 裁剪图像已保存为 " << cropped_filename << std::endl;
    }

    // 显示结果图像
    cv::imshow("Blue Rectangles Detection", image);
    cv::waitKey(0);
    cv::destroyAllWindows();

    return 0;
}
